﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;

namespace 解决JWT无法撤回的问题.Controllers
{
    [Route("[controller]/[action]")]
    [ApiController]
    public class Test1Controller : ControllerBase
    {
        private static string BuildToken(IEnumerable<Claim> claims, JWTOptions options)
        {
            DateTime expires = DateTime.Now.AddSeconds(options.ExpireSeconds);
            byte[] keyBytes = Encoding.UTF8.GetBytes(options.SigningKey);
            var secKey = new SymmetricSecurityKey(keyBytes);
            var credentials = new SigningCredentials(secKey,
                SecurityAlgorithms.HmacSha256Signature);
            var tokenDescriptor = new JwtSecurityToken(expires: expires,
                signingCredentials: credentials, claims: claims);
            return new JwtSecurityTokenHandler().WriteToken(tokenDescriptor);
        }

        //token:
        //version0:eyJhbGciOiJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L3htbGRzaWctbW9yZSNobWFjLXNoYTI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6ImFkbWluIiwiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNS8wNS9pZGVudGl0eS9jbGFpbXMvbmFtZSI6ImFkbWluIiwiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93cy8yMDA4LzA2L2lkZW50aXR5L2NsYWltcy92ZXJzaW9uIjoiMCIsImh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd3MvMjAwOC8wNi9pZGVudGl0eS9jbGFpbXMvcm9sZSI6WyJhZG1pbiIsIm1hbmFnZXIiXSwiZXhwIjoxNjYyMTY5NDcyfQ.I2oB5Qhhe-ZGN9do4eIIdk98uQOPvrIUg2bo3j0gEGE

        //version1:eyJhbGciOiJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L3htbGRzaWctbW9yZSNobWFjLXNoYTI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6ImFkbWluIiwiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNS8wNS9pZGVudGl0eS9jbGFpbXMvbmFtZSI6ImFkbWluIiwiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93cy8yMDA4LzA2L2lkZW50aXR5L2NsYWltcy92ZXJzaW9uIjoiMSIsImh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd3MvMjAwOC8wNi9pZGVudGl0eS9jbGFpbXMvcm9sZSI6WyJhZG1pbiIsIm1hbmFnZXIiXSwiZXhwIjoxNjYyMTY5NjMxfQ.5MCBQoGlA2z84GLAnvTjgneFTdaVZ5uKeO9txKpumPQ


        [HttpPost]
        [NotCheckJWTVersion]
        public async Task<IActionResult> Login2(LoginRequest req,
                   [FromServices] IOptions<JWTOptions> jwtOptions)
        {
            string userName = req.UserName;
            string password = req.Password;

            if (userName=="admin" && password=="123456")
            {
                UserModel user = null;

                DataCenter.UserData.TryGetValue(userName,out user);

                if (user==null)
                {
                    user = new UserModel();
                    user.UserName = userName;
                    user.JWTVersion=0;
                    DataCenter.UserData.Add(user.UserName,user);
                }
                else
                {
                    user.JWTVersion++;
                }               
               
                var claims = new List<Claim>();
                claims.Add(new Claim(ClaimTypes.NameIdentifier, user.UserName.ToString()));
                claims.Add(new Claim(ClaimTypes.Name, user.UserName));
                claims.Add(new Claim(ClaimTypes.Version, user.JWTVersion.ToString()));
              
                claims.Add(new Claim(ClaimTypes.Role, "admin"));  
                claims.Add(new Claim(ClaimTypes.Role, "manager"));

                //可以加多个相同的ClaimTypes,登录成功取出的时候就要用FindAll了
                // IEnumerable<Claim> roleClaims = User.FindAll(ClaimTypes.Role);
                //string roleNames = string.Join(',', roleClaims.Select(c => c.Value));

                string jwtToken = BuildToken(claims, jwtOptions.Value);

                return Ok(jwtToken);
            }
            else
            {
                return BadRequest("Failed");
            }

        }
    }
}
